package com.zk.algorithm.string;

import com.zk.algorithm.Utils;
import com.zk.algorithm.annotation.Easy;
import com.zk.algorithm.annotation.LeetCodeExplore;

/**
 * @author zk
 */
@Easy
@LeetCodeExplore
public class StringToInteger {

    // 4193 with words => 4193
    //     -42 => -42
    // 42 => 42
    // words and 987 => 0
    // -91283472332 => -2147483648
    public int myAtoi(String str) {
        if (str == null || str.isEmpty()) {
            return 0;
        }

        int start = 0;
        int end = str.length() - 1;

        int ans = 0;
        char sign = 0;
        boolean inParsing = false;

        while (start <= end) {
            char c = str.charAt(start);

            if (c >= '0' && c <= '9') {
                int before = ans;
                ans = ans * 10 + (c - '0');
                if (isOverflow(before, ans)) {
                    if (sign == '-') {
                        return Integer.MIN_VALUE;
                    }

                    return Integer.MAX_VALUE;
                }

                inParsing = true;
            } else if (c == '-' || c == '+') {
                if (inParsing) {
                    return resultWithSign(sign, ans);
                }

                sign = c;
                inParsing = true;
            } else if (c == ' ') {
                if (inParsing) {
                    return resultWithSign(sign, ans);
                }
            } else {
                return resultWithSign(sign, ans);
            }

            start++;
        }

        return resultWithSign(sign, ans);
    }

    private boolean isOverflow(int before, int after) {
        return after / 10 != before;
    }

    private int resultWithSign(char sign, int res) {
        if (sign == '-') {
            return -res;
        }

        return res;
    }

    public static void main(String...args) {
        StringToInteger stringToInteger = new StringToInteger();

        Utils.println(stringToInteger.myAtoi("42"));
        Utils.println(stringToInteger.myAtoi("   -42"));
        Utils.println(stringToInteger.myAtoi("4193 with words"));
        Utils.println(stringToInteger.myAtoi("words and 987"));
        Utils.println(stringToInteger.myAtoi("-91283472332"));
        Utils.println(stringToInteger.myAtoi("-91283472332"));
        Utils.println(stringToInteger.myAtoi("21 4748 3647"));
        Utils.println(stringToInteger.myAtoi("2147483647"));
        Utils.println(stringToInteger.myAtoi("2147483648"));
        Utils.println(stringToInteger.myAtoi("-2147483648"));
        Utils.println(stringToInteger.myAtoi("-2147483649"));
        Utils.println(stringToInteger.myAtoi("  -0012a42"));
        Utils.println(stringToInteger.myAtoi("   +0 123"));
        Utils.println(stringToInteger.myAtoi("0-1"));
        Utils.println(stringToInteger.myAtoi("-5-"));
    }

}
